import Matrix4 from '../Core/Matrix4.js';

    /**
     * A model node with a transform for user-defined animations.  A glTF asset can
     * contain animations that target a node's transform.  This class allows
     * changing a node's transform externally so animation can be driven by another
     * source, not just an animation in the glTF asset.
     * <p>
     * Use {@link Model#getNode} to create an instance.
     * </p>
     *
     * @alias ModelNode
     * @internalConstructor
     * @class
     *
     * @example
     * var node = model.getNode('LOD3sp');
     * node.matrix = Cesium.Matrix4.fromScale(new Cesium.Cartesian3(5.0, 1.0, 1.0), node.matrix);
     *
     * @see Model#getNode
     */
    function ModelNode(model, node, runtimeNode, id, matrix) {
        this._model = model;
        this._runtimeNode = runtimeNode;
        this._name = node.name;
        this._id = id;

        /**
         * @private
         */
        this.useMatrix = false;

        this._show = true;
        this._matrix = Matrix4.clone(matrix);
        this._originalMatrix = Matrix4.clone(matrix);
    }

    Object.defineProperties(ModelNode.prototype, {
        /**
         * The value of the <code>name</code> property of this node.
         *
         * @memberof ModelNode.prototype
         *
         * @type {String}
         * @readonly
         */
        name : {
            get : function() {
                return this._name;
            }
        },

        /**
         * The index of the node.
         *
         * @memberof ModelNode.prototype
         *
         * @type {String}
         * @readonly
         */
        id : {
            get : function() {
                return this._id;
            }
        },

        /**
         * Determines if this node and its children will be shown.
         *
         * @memberof ModelNode.prototype
         * @type {Boolean}
         *
         * @default true
         */
        show : {
            get : function() {
                return this._show;
            },
            set : function(value) {
                if (this._show !== value) {
                    this._show = value;
                    this._model._perNodeShowDirty = true;
                }
            }
        },

        /**
         * The node's 4x4 matrix transform from its local coordinates to
         * its parent's.
         * <p>
         * For changes to take effect, this property must be assigned to;
         * setting individual elements of the matrix will not work.
         * </p>
         *
         * @memberof ModelNode.prototype
         * @type {Matrix4}
         */
        matrix : {
            get : function() {
                return this._matrix;
            },
            set : function(value) {
                this._matrix = Matrix4.clone(value, this._matrix);
                this.useMatrix = true;

                var model = this._model;
                model._cesiumAnimationsDirty = true;
                this._runtimeNode.dirtyNumber = model._maxDirtyNumber;
            }
        },

        /**
         * Gets the node's original 4x4 matrix transform from its local coordinates to
         * its parent's, without any node transformations or articulations applied.
         *
         * @memberof ModelNode.prototype
         * @type {Matrix4}
         */
        originalMatrix : {
            get : function() {
                return this._originalMatrix;
            }
        }
    });

    /**
     * @private
     */
    ModelNode.prototype.setMatrix = function(matrix) {
        // Update matrix but do not set the dirty flag since this is used internally
        // to keep the matrix in-sync during a glTF animation.
        Matrix4.clone(matrix, this._matrix);
    };
export default ModelNode;
